package wq.gdky005.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.util.Log;

/**
 * 增强型Http辅助类
 * 
 * @author wangqing 2013-5-24
 */
public class HttpUtil {

	private static HttpClient httpClient;
	private static final String TAG = "HttpUtil";

	/**
	 * 获得线程安全的HttpClient对象，能够适应多线程环境
	 * wangqing
	 * 2013-5-24
	 * HttpClient
	 * @return
	 */
	public static synchronized HttpClient getHttpClient() {

		if (null == httpClient) {
			HttpParams params = new BasicHttpParams();
			// 设置基本的参数
			HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
			HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
			HttpProtocolParams.setUseExpectContinue(params, true);
			/* 默认不需要带上，如果需要，就在参数中添加 */
			// HttpProtocolParams.setUserAgent(params,
			// "Mozilla/5.0(Linux;U;Android 2.2.1;en-us;Nexus One Build.FRG83)");
			// 超时设置
			/* 从连接池中取连接的超时时间 */
			ConnManagerParams.setTimeout(params, 1000);
			/* 连接超时 */
			HttpConnectionParams.setConnectionTimeout(params, 1000);
			/* 请求超时 */
			HttpConnectionParams.setSoTimeout(params, 4000);

			// 设置我们的HttpClient支持HTTP和HTTPS两种模式
			SchemeRegistry schemeRegistry = new SchemeRegistry();
			schemeRegistry.register(new Scheme("http", PlainSocketFactory
					.getSocketFactory(), 80));
			schemeRegistry.register(new Scheme("https", SSLSocketFactory
					.getSocketFactory(), 443));

			// 使用线程安全的连接管理来创建HttpClient
			ClientConnectionManager conManager = new ThreadSafeClientConnManager(
					params, schemeRegistry);
			httpClient = new DefaultHttpClient(conManager, params);

		}

		return httpClient;
	}

	/**
	 * 使用List<BasicNameValuePair> 获得Post请求对象
	 * wangqing
	 * 2013-5-24
	 * HttpPost
	 * @param uri
	 * @param params
	 * @return
	 */
	public static HttpPost getPost(String uri, List<BasicNameValuePair> params) {
		HttpPost post = new HttpPost(uri);

		if (params != null) {
			try {
				post.setEntity(new UrlEncodedFormEntity(params));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				TestUtils.logE("UnsupportedEncodingException");
			}
		}

		return post;
	}
	
	/**
	 * 使用Map<String, String> 获得Post请求对象
	 * wangqing
	 * 2013-5-24
	 * HttpPost
	 * @param uri
	 * @param params
	 * @return
	 */
	public static HttpPost getPost(String uri, Map<String, String> mapParams) {
		
		
		
		HttpPost post = new HttpPost(uri);
		
		if (mapParams != null) {
			
			//封装数据集合
			List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
			for (Entry<String, String> value : mapParams.entrySet()) {
				params.add(new BasicNameValuePair(value.getKey(), value.getValue()));
			}
			
			try {
				post.setEntity(new UrlEncodedFormEntity(params));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				TestUtils.logE("UnsupportedEncodingException");
			}
		}
		
		return post;
	}

	/**
	 * 用户使用的方法 
     * 功能：从服务器获得字符串
	 * wangqing
	 * 2013-5-24
	 * String
	 * @param post
	 * @return
	 */
	public static String getString(HttpPost post) {
		HttpClient httpClient = getHttpClient();
		HttpResponse response;

		try {
			response = httpClient.execute(post);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				post.abort();
				TestUtils.logE("响应失败，请求终止");
			}
			TestUtils.logI("响应成功");
			return EntityUtils.toString(response.getEntity());
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			TestUtils.logE("ClientProtocolException");
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			TestUtils.logE("IOException");
			return null;
		}
	}
	
	/**
	 * 用户使用的方法 
     * 功能：请求服务器，返回字符串 
     * @param post post 请求对象 
     * @param requestLimit 请求失败限制次数
	 * wangqing
	 * 2013-5-24
	 */
	public static String getString(HttpPost post, int requestLimit) {
		
		if (requestLimit < 1) {
			return null;
		}
		HttpResponse response;
		int currCount = 0;	//当前请求次数
		String result = null;
		
		while (currCount < requestLimit) {
			
			HttpClient httpClient = getHttpClient();
			currCount++;
			try {
				response = httpClient.execute(post);
				if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
					TestUtils.logI("响应成功");
					return EntityUtils.toString(response.getEntity());
				} else {
					post.abort();
					TestUtils.logE("响应失败，请求终止");
					result = "响应失败，请求终止";
				}
			} catch (ClientProtocolException e) {
				e.printStackTrace();
				TestUtils.logE("ClientProtocolException");
				if (currCount > requestLimit) {
					result = "请求失败";
					break;
				}
				
			} catch (IOException e) {
				e.printStackTrace();
				if (e instanceof ConnectTimeoutException) {
					result = "连接超时";
					TestUtils.logE("ConnectTimeoutException");
				} else {
					result = "IO异常";
					TestUtils.logE("IOException");
				}
				if (currCount > requestLimit) {
					break;
				}
			} finally {
				TestUtils.logI("finally");
			}
		}
		return result;
	}
	
	public static String getString(String uri, int requestLimit) {
		
		return null;
	}
	
	/**
	 * 释放建立http请求占用的资源 
	 * wangqing
	 * 2013-5-24
	 * void
	 */
	public static void shutdown() {
		//释放建立http请求占用的资源
		httpClient.getConnectionManager().shutdown();
		httpClient = null;
	}

}
